from typing import Generic, TypeVar, Optional
from pydantic import BaseModel
from sqlalchemy.orm import Query
from math import ceil

T = TypeVar('T')

class PaginationParams(BaseModel):
    """分页参数"""
    page: int = 1
    size: int = 10

class PaginatedResponse(BaseModel, Generic[T]):
    """分页响应"""
    items: list[T]
    total: int
    page: int
    size: int
    pages: int

def paginate_query(query: Query, params: PaginationParams) -> Query:
    """对SQLAlchemy查询进行分页"""
    return query.offset((params.page - 1) * params.size).limit(params.size)

def paginate(items: list[T], total: int, page: int, size: int) -> PaginatedResponse[T]:
    """构建分页响应"""
    return PaginatedResponse[T](
        items=items,
        total=total,
        page=page,
        size=size,
        pages=ceil(total / size) if size > 0 else 0
    )

def apply_pagination(query: Query, params: PaginationParams) -> PaginatedResponse[T]:
    """应用分页并返回分页结果"""
    total = query.count()
    items = paginate_query(query, params).all()
    return paginate(items, total, params.page, params.size)